/* $$Id: Settings.java 33 2008-01-10 16:17:18Z qxodream $$
 *
 * RssReaderMidlet --  RSS reader for J2ME(midp)
 * The original codes of this porgram is from
 * RssOwlMIDlet(zhengyun@gmail.com)
 *
 * Copyright (c) 2007-2008 QXO(qxodream@gmail.com)
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation; either version 2 of the License, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */

package com.ultrapower.tools;

import java.io.IOException;
import java.util.Vector;

import javax.microedition.midlet.MIDlet;
import javax.microedition.rms.RecordComparator;
import javax.microedition.rms.RecordEnumeration;
import javax.microedition.rms.RecordStore;
import javax.microedition.rms.RecordStoreException;

import com.ultrapower.control.GUIController;
import com.ultrapower.model.RssFeed;

/**
 * 类说明：利用J2ME的RMS存储读取数据的接口<br/> 封装了对Rss Feeds在RMS中存取的操作. 总的来说，改变还是比较大的，
 * 原来Tommi将Feed列表以及URL存储在RMS的一个条目， 我放弃了这种做法，而是像garrey处理电话记录一样.<br/> 创建人: Tommi
 * Laukkanen <br/> 修改者: zhengyun@ultrapower 2005.10.07
 */
public class Settings {
	private static Settings m_settings;
	private MIDlet m_midlet;
	private static RecordStore m_store;
	private boolean m_valuesChanged = false;
	private GUIController controller;

	public Settings(GUIController control, MIDlet midlet) throws IOException,
			RecordStoreException {
		System.out.println("!-- Settings another Constructor --!\n");
		controller = control;
		m_midlet = midlet;
		openStore();
	}

	/**
	 * Singleton pattern is used to return only one instance of record store
	 */
	public static synchronized Settings getInstance(GUIController control,
			MIDlet midlet) throws IOException, RecordStoreException {
		if (m_settings == null) {
			System.out.println("!-- Settings::getInstance --!\n");
			m_settings = new Settings(control, midlet);
		}
		return m_settings;
	}

	/** Constructor */
	// private Settings( MIDlet midlet )
	// throws IOException, RecordStoreException {
	// System.out.println("!-- Settings default Constructor --!\n");
	// m_midlet = midlet;
	// openStore();
	// }
	/** Load properties from record store */
	private synchronized void openStore() throws IOException,
			RecordStoreException {

		System.out.println("!-- Begin load --!\n");

		m_valuesChanged = false;

		try {
			m_store = RecordStore.openRecordStore(ResUtils.RECORDSTORE_NAME,
					true);
			if (m_store.getNumRecords() == 0) {
				System.out.println("!-- 没有记录 --!\n");

				// 如果没有在记录中找到Rss Feed，我们就自己给记录中加入预定义的一些RssFeed
				DefaultRssFeeds();
			} else {
				System.out.println("!-- 找到了上次的记录 --!\n");
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	// 关闭RecordStore
	public synchronized void closeStore() {
		if (m_store != null) {
			try {
				m_store.closeRecordStore();
				m_store = null;
			} catch (RecordStoreException ex) {
				ex.printStackTrace();
			}
		}
	}

	/***************************************************************************
	 * // Settings::DefaultRssFeeds // // Description: // 如果没有在记录中找到Rss
	 * Feed，我们就自己给记录中加入预定义的一些RssFeed // // Parameters: // Return Values: //
	 * Remark: 往RMS中实际存入预定义的Rss Feeds,这样在用户手机上一开始就有可供浏览的RSS源了 // Author: //
	 * zhengyun@ultrapower 2005.10.07 //
	 **************************************************************************/
	private void DefaultRssFeeds() throws IOException, RecordStoreException {
		System.out.println("!-- Enter DefaultRssFeeds --!");

		String[] feeds = ResUtils.getFeeds();
		for (int i = 0; i < feeds.length; i++) {
			final String feed = feeds[i];
			final byte[] dataInitRssFeed = feed.getBytes("UTF-8");
			m_store.addRecord(dataInitRssFeed, 0, dataInitRssFeed.length);
		}
		// byte[] dataInitRssFeed =
		// String.valueOf(SResources.getChars(SResources.TXT_T_RSSFEED1)).getBytes();
		// m_store.addRecord( dataInitRssFeed, 0, dataInitRssFeed.length );
		//
		// dataInitRssFeed =
		// String.valueOf(SResources.getChars(SResources.TXT_T_RSSFEED2)).getBytes();
		// m_store.addRecord( dataInitRssFeed, 0, dataInitRssFeed.length );
		//
		// dataInitRssFeed =
		// String.valueOf(SResources.getChars(SResources.TXT_T_RSSFEED3)).getBytes();
		// m_store.addRecord( dataInitRssFeed, 0, dataInitRssFeed.length );
		//
		// dataInitRssFeed =
		// String.valueOf(SResources.getChars(SResources.TXT_T_RSSFEED4)).getBytes();
		// m_store.addRecord( dataInitRssFeed, 0, dataInitRssFeed.length );
		//
		// dataInitRssFeed =
		// String.valueOf(SResources.getChars(SResources.TXT_T_RSSFEED5)).getBytes();
		// m_store.addRecord( dataInitRssFeed, 0, dataInitRssFeed.length );
		//
		// dataInitRssFeed =
		// String.valueOf(SResources.getChars(SResources.TXT_T_RSSFEED6)).getBytes();
		// m_store.addRecord( dataInitRssFeed, 0, dataInitRssFeed.length );
		//
		// dataInitRssFeed =
		// String.valueOf(SResources.getChars(SResources.TXT_T_RSSFEED7)).getBytes();
		// m_store.addRecord( dataInitRssFeed, 0, dataInitRssFeed.length );

		// dataInitRssFeed = null;
	}

	// /***************************************************************************
	// * // Settings::addRssFeed // // Description: // 向RMS中存储一条RssFeed // //
	// * Parameters: feed: 封装了feed的名称、URL的类实体 // Return Values: int:
	// * 存储在RMS中的序号,可供以后找到这条记录 // Remark: // Author: // zhengyun@ultrapower
	// * 2005.10.07 //
	// **************************************************************************/
	// public int addRssFeed(RssFeed feed) {
	//
	// try {
	// byte[] data = feed.getStoreString().getBytes();
	// int id = m_store.getNextRecordID();
	// System.out.println("!-- 添加记录:" + id);
	// int rec = m_store.addRecord(data, 0, data.length);
	// System.out.println("rec:" + rec);
	// return id;
	// } catch (RecordStoreException ex) {
	// }
	//
	// return -1;
	// }

	/**
	 * 保存Rss Feed,当id=0时新增记录;不为0时更新记录
	 *
	 * @param feed -
	 *            待保存的RssFeed
	 * @return feed对应的ID
	 */
	public int saveRssFeed(RssFeed feed) {
		try {
			byte[] data = feed.getStoreString().getBytes();
			int id = feed.getId();
			if (id == 0) {
				// TODO 已存在指定url的rss feed
				id = m_store.getNextRecordID();
				System.out.println("!-- 添加记录:" + id);
				int rec = m_store.addRecord(data, 0, data.length);
				System.out.println("rec:" + rec);
			} else {
				System.out.println("!-- 编辑记录:" + id);
				m_store.setRecord(id, data, 0, data.length);
			}
			return id;
		} catch (RecordStoreException ex) {
			ex.printStackTrace();
		}

		return -1;
	}

	// /***************************************************************************
	// * // Settings::updateRssFeed // // Description: // 在RMS找到指定的RssFeed并刷新它
	// // //
	// * Parameters: feed: 封装了feed的名称、URL的类实体 // Return Values: // Remark: //
	// * Author: // zhengyun@ultrapower 2005.10.07 //
	// **************************************************************************/
	// public void updateRssFeed(RssFeed feed) {
	//
	// try {
	// int id = feed.getId();
	// System.out.println("!-- 编辑记录:" + id);
	// byte[] data = feed.getStoreString().getBytes();
	// m_store.setRecord(id, data, 0, data.length);
	//
	// } catch (RecordStoreException ex) {
	// }
	// }

	/***************************************************************************
	 * // Settings::getRssFeed // // Description: // 访问一条记录 // // Parameters:
	 * id: feed在RMS中存储的序号 // Return Values: RssFeed: 找到后,就返回这个Feed实体 // Remark: //
	 * Author: // zhengyun@ultrapower 2005.10.07 //
	 **************************************************************************/
	public RssFeed getRssFeed(int id) {
		RssFeed feed = null;

		try {
			System.out.println("!-- 访问记录:" + id);
			feed = new RssFeed(id, m_store.getRecord(id));
		} catch (RecordStoreException ex) {
		}

		return feed;
	}

	/***************************************************************************
	 * // Settings::deleteRssFeed // // Description: // 删除一条记录 // // Parameters:
	 * id: feed在RMS中存储的序号 // Return Values: // Remark: // Author: //
	 * zhengyun@ultrapower 2005.10.07 //
	 **************************************************************************/
	public void deleteRssFeed(int id) {
		try {
			System.out.println("!-- 删除记录:" + id);
			m_store.deleteRecord(id);
		} catch (RecordStoreException ex) {
		}
	}

	/***************************************************************************
	 * // Settings::getRssFeeds // // Description: // 获取RMS中存储的所有的Feed列表 // //
	 * Parameters: // Return Values: Vector: 包含了所有存储的Rss Feed列表 // Remark:
	 * 首先枚举出指定Store中所有的记录,遍历每一条记录,如果是RssFeed, 就将它插入到Vector中，最后返回这个包含了所有存储的Rss
	 * Feed。 // Author: // zhengyun@ultrapower 2005.10.07 //
	 **************************************************************************/
	public Vector getRssFeeds() {

		// 先重新加载
		/*
		 * try{ openStore(); } catch(Exception exc){}
		 */

		Vector bookmarks = new Vector(ResUtils.MAX_FEEDS);
		RecordEnumeration enums = null;
		int ind = 0;
		try {
			RssFeed feed = null;
			enums = m_store.enumerateRecords(null, new RssFeedComparator(),
					false);
			if (enums != null) {
				while (enums.hasPreviousElement()) {
					// ind = enums.previousRecordId();

					// previousRecordId also advances the record pointer, so we
					// have no
					// need to call previousRecord() as well.
					ind = enums.previousRecordId();

					// Retrieve the data from the next record
					// and make it the current record
					// Set up a byte array buffer and some helper streams
					byte[] rec = new byte[m_store.getRecordSize(ind)];
					rec = m_store.getRecord(ind);
					System.out.println("本次遍历的id为:" + ind);

					if (rec != null) {
						try {
							feed = new RssFeed(ind, rec);
						} catch (Exception e) {
							// Debug
							System.out.println("添加RssFeed时发生了异常:"
									+ e.toString());
						} finally {
							// Add the feed item to the Vector
							bookmarks.addElement(feed);
							System.out.println("本次遍历的feed为:\n+"
									+ feed.getName() + "+\n" + feed.getUrl());
							rec = null;
							feed = null;
						}
					}
				}
				System.out.println("!-- 记录枚举遍历完毕 --!");
			} else {
				System.out.println("!-- enums is null! --!");
			}

		} catch (Exception ex) {
			ex.printStackTrace();
		} finally {
			try {
				enums.destroy();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}// end finally

		return bookmarks;
	}

	/***************************************************************************
	 * // Settings::RssFeedComparator // // Description: // 一个简单的比较器 // 更详细信息参看 //
	 * http://www.zdnet.com.cn/developer/code/story/0,2000081534,39068540,00.htm //
	 * <探索J2ME：对记录进行排序> // // Author: // zhengyun@ultrapower 2005.10.07 //
	 **************************************************************************/
	private class RssFeedComparator implements RecordComparator {

		// private ByteArrayInputStream stream;
		// private DataInputStream reader;

		public int compare(byte[] bytes, byte[] bytes1) {
			// long d1 = 0, d2 = 0;
			//
			// try {
			// // Compares records, sorts them
			// // in descending order
			//
			// //Retrieve ExpenseDate from the first record
			// stream = new ByteArrayInputStream(bytes);
			// reader = new DataInputStream(stream);
			// //Get our date from the byte stream
			// //in "number of milliseconds in epoch" format
			// d1 = reader.readLong();
			//
			// //Retrieve ExpenseDate from the second record
			// stream = new ByteArrayInputStream(bytes1);
			// reader = new DataInputStream(stream);
			// //Get our date from the byte stream
			// d2 = reader.readLong();
			// }
			// catch (Exception e) {
			// // Debug
			// System.out.println("RssFeedComparator Exception:" +
			// e.toString());
			// } finally {
			// if (d1 == d2) {
			// return RssFeedComparator.EQUIVALENT;
			// } else if (d1 > d2) {
			// return RssFeedComparator.PRECEDES;
			// } else {
			// return RssFeedComparator.FOLLOWS;
			// }
			// }
			return RssFeedComparator.FOLLOWS;
		}
	}

	public MIDlet getM_midlet() {
		return m_midlet;
	}

	public void setM_midlet(MIDlet m_midlet) {
		this.m_midlet = m_midlet;
	}

	public boolean isM_valuesChanged() {
		return m_valuesChanged;
	}

	public void setM_valuesChanged(boolean changed) {
		m_valuesChanged = changed;
	}

	public GUIController getController() {
		return controller;
	}

	public void setController(GUIController controller) {
		this.controller = controller;
	}
}
